home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
027a
/
agraph.zip
/
AGRAPH.PRG
next >
Wrap
Text File
|
1991-05-16
|
14KB
|
428 lines
* Compile with /n option
* The following constant determines the density of y axis labels
#define YDENSITY 80
#define BAR 1
#define LINE 2
static _xOrg,_yOrg,_width,_height,_yMin,_yMax
static _xDivs,_xInc,_yDivs,_yScale,_decimals,_GraphType := 0
************************************************************************
* Auto Clustered Bar Graphing Function
*
* Parameters:
* All parameters other than data are optional
*
* data contains an array of data values. If more than one group is
* desired (i.e., clustered bars) the array should contain an
* array of arrays, where each sub array contains the data points
* for each cluster.
* width Width of graph in screen units.
* height Height of graph in screen units.
* xOrg x position of lower left corner.
* yOrg y position of lower left corner.
* attr array of {pattern, color}, used for groups. The size should
* be the same as each of the data sub arrays.
* yMin override for y minimum
* yMax override for y maximum
************************************************************************
procedure ACBarGraph(data,width,height,xOrg,yOrg,attr,yMin,yMax)
local i,j
AutoCommon(@data,@width,@height,@xOrg,@yOrg,@yMin,@yMax)
// Determine scaling values
_xInc := int(_width/_xDivs)
_yScale := _height/(_yMax-_yMin)
_width := _xInc*_xDivs // adjust width
// Scale and store the data.
datareset()
for i := 1 to _xDivs
for j := 1 to len(data[i])
datastore((data[i,j]-yMin)*_yScale, ;
if(attr==nil,j,attr[j,1]), ;
0, ;
if(attr==nil,j,attr[j,2]))
next j
next i
// Draw the graph
clipwin(_xOrg,_yOrg,_xOrg+_width,_yOrg+_height)
bargraph(_xOrg+_xInc/(2*len(data[1])+2),_yOrg,_xInc,2,len(data[1]))
clipwin(0,0,1350,1000)
_GraphType := BAR
return
************************************************************************
* Auto Clustered 3D Bar Graphing Function
*
* Parameters:
* All parameters other than data are optional
*
* data contains an array of data values. If more than one group is
* desired (i.e., clustered bars) the array should contain an
* array of arrays, where each sub array contains the data points
* for each cluster.
* width Width of graph in screen units.
* height Height of graph in screen units.
* xOrg x position of lower left corner.
* yOrg y position of lower left corner.
* attr array of {pattern, color}, used for groups. The size should
* be the same as each of the data sub arrays.
* yMin override for y minimum
* yMax override for y maximum
************************************************************************
procedure ACBar3DGraph(data,width,height,xOrg,yOrg,attr,yMin,yMax)
local i,j
AutoCommon(@data,@width,@height,@xOrg,@yOrg,@yMin,@yMax)
// Determine scaling values
_xInc := int(_width/_xDivs)
_yScale := _height/(_yMax-_yMin)
_width := _xInc*_xDivs // adjust width
// Scale and store the data.
datareset()
for i := 1 to _xDivs
for j := 1 to len(data[i])
datastore((data[i,j]-yMin)*_yScale, ;
if(attr==nil,j,attr[j,1]), ;
0, ;
if(attr==nil,j,attr[j,2]))
next j
next i
// Draw the graph
clipwin(_xOrg,_yOrg,_xOrg+_width,_yOrg+_height)
bargraph(_xOrg+_xInc/(2*len(data[1])+2),_yOrg,_xInc,2+16,len(data[1]))
clipwin(0,0,1350,1000)
_GraphType := BAR
return
************************************************************************
* Auto Stacked Bar Graphing Function
*
* Parameters:
* All parameters other than data are optional
*
* data contains an array of data values. If more than one group is
* desired (i.e., clustered bars) the array should contain an
* array of arrays, where each sub array contains the data points
* for each cluster.
* width Width of graph in screen units.
* height Height of graph in screen units.
* xOrg x position of lower left corner.
* yOrg y position of lower left corner.
* attr array of {pattern, color}, used for groups. The size should
* be the same as each of the data sub arrays.
* yMin override for y minimum
* yMax override for y maximum
************************************************************************
procedure ASBarGraph(data,width,height,xOrg,yOrg,attr,yMin,yMax)
local i,j,t
if len(data[1]) > 1 // add an extra sum group
for i := 1 to len(data)
t := 0
for j := 1 to len(data[i])
t += data[i,j]
next j
aadd(data[i],t)
next i
end
AutoCommon(@data,@width,@height,@xOrg,@yOrg,@yMin,@yMax)
if len(data[1]) > 1 // kill sum group
for i := 1 to len(data)
asize(data[i],len(data[i])-1)
next
end
// Determine scaling values
_xInc := int(_width/_xDivs)
_yScale := _height/(_yMax-_yMin)
_width := _xInc*_xDivs // adjust width
// Scale and store the data.
datareset()
for i := 1 to _xDivs
for j := 1 to len(data[i])
datastore((data[i,j]-yMin)*_yScale, ;
if(attr==nil,j,attr[j,1]), ;
0, ;
if(attr==nil,j,attr[j,2]))
next j
next i
// Draw the graph
clipwin(_xOrg,_yOrg,_xOrg+_width,_yOrg+_height)
bargraph(_xOrg+_xInc/4,_yOrg,_xInc,1,len(data[1]))
clipwin(0,0,1350,1000)
_GraphType := BAR
return
************************************************************************
* Auto Stacked 3D Bar Graphing Function
*
* Parameters:
* All parameters other than data are optional
*
* data contains an array of data values. If more than one group is
* desired (i.e., clustered bars) the array should contain an
* array of arrays, where each sub array contains the data points
* for each cluster.
* width Width of graph in screen units.
* height Height of graph in screen units.
* xOrg x position of lower left corner.
* yOrg y position of lower left corner.
* attr array of {pattern, color}, used for groups. The size should
* be the same as each of the data sub arrays.
* yMin override for y minimum
* yMax override for y maximum
************************************************************************
procedure ASBar3DGraph(data,width,height,xOrg,yOrg,attr,yMin,yMax)
local i,j,t
if len(data[1]) > 1 // add an extra sum group
for i := 1 to len(data)
t := 0
for j := 1 to len(data[i])
t += data[i,j]
next j
aadd(data[i],t)
next i
end
AutoCommon(@data,@width,@height,@xOrg,@yOrg,@yMin,@yMax)
if len(data[1]) > 1 // kill sum group
for i := 1 to len(data)
asize(data[i],len(data[i])-1)
next
end
// Determine scaling values
_xInc := int(_width/_xDivs)
_yScale := _height/(_yMax-_yMin)
_width := _xInc*_xDivs // adjust width
// Scale and store the data.
datareset()
for i := 1 to _xDivs
for j := 1 to len(data[i])
datastore((data[i,j]-yMin)*_yScale, ;
if(attr==nil,j,attr[j,1]), ;
0, ;
if(attr==nil,j,attr[j,2]))
next j
next i
// Draw the graph
clipwin(_xOrg,_yOrg,_xOrg+_width,_yOrg+_height)
bargraph(_xOrg+_xInc/4,_yOrg,_xInc,1+16,len(data[1]))
clipwin(0,0,1350,1000)
_GraphType := BAR
return
************************************************************************
* Auto Line Graphing Function
*
* Parameters:
* All parameters other than data are optional
*
* data Contains an array of data values. If more than one group is
* desired (i.e., multiple lines) the array should contain an
* array of arrays, where each sub array contains the data points
* for each data set.
* width Width of graph in screen units.
* height Height of graph in screen units.
* xOrg x position of lower left corner.
* yOrg y position of lower left corner.
* attr Array of {icon, color}, used for sets. The size should be the
* same as each of the data sub arrays.
* yMin Override for y minimum
* yMax Override for y maximum
************************************************************************
procedure ALineGraph(data,width,height,xOrg,yOrg,attr,yMin,yMax)
local i,j,drawflag,x,y
AutoCommon(@data,width,height,xOrg,yOrg,yMin,yMax)
// Determine scaling values
_xInc := _width/(_xDivs-1)
_yDivs := int(_height/YDENSITY+.5) // number of y axis divisions
_decimals := tic(@_yMin,@_yMax,@_yDivs)
_yScale := _height/(_yMax-_yMin)
clipwin(_xOrg,_yOrg,_xOrg+_width,_yOrg+_height)
// Scale and graph the data.
for i := 1 to len(data[1])
drawflag := .F.
for j := 1 to _xDivs
if data[j,i] == nil // stop drawing at nil data
drawflag := .F.
else
x := _xOrg+(j-1)*_xInc
y := _yOrg+(data[j,i]-_yMin)*_yScale
if (x>=0 .and. x<=1350 .and. y>=0 .and. y<=1000)
drawicon(x,y,4,if(attr==nil,i,attr[i,1]),if(attr==nil,i,attr[i,2]))
end
drawline(x,y,x,y,if(drawflag,16,0),0,if(attr==nil,i,attr[i,2]))
drawflag := .T.
end
next j
next i
clipwin(0,0,1350,1000)
_GraphType := LINE
return
procedure ALabel(xLabels,LColor)
local i
if LColor = nil
LColor := 15 // default to White
end
if _GraphType == 0 // Abort if no previous graph
return
end
if _GraphType == BAR
xyaxes(_xOrg,_yOrg,_xInc*_xDivs,_height,_xDivs,_yDivs,0,LColor)
else
xyaxes(_xOrg,_yOrg,_width,_height,_xDivs-1,_yDivs,0,LColor)
endif
// Draw y axis labels
if (_xOrg-15>=0 .and. _xOrg-15<=1350)
for i := 0 to _yDivs
if _yOrg+i*_height/_yDivs>=0 .and. _yOrg+i*_height/_yDivs<=1000
saystring(_xOrg-15,_yOrg+i*_height/_yDivs,4,0+16+64,LColor,;
str(_yMin+i*(_yMax-_yMin)/_yDivs,10,_decimals))
end
end
end
// Draw x axis labels
if _yOrg-15>=0 .and. _yOrg-15<=1000 .and. xlabels <> nil
for i := 1 to _xDivs
if _GraphType == BAR
if _xOrg+i*_xInc-_xInc/2>=0 .and. _xOrg+i*_xInc-_xInc/2<=1350
saystring(_xOrg+i*_xInc-_xInc/2,_yOrg-15,4,0+8+128,LColor,;
trim(xlabels[i]))
end
else
if _xOrg+(i-1)*_xInc>=0 .and. _xOrg+(i-1)*_xInc<=1350
saystring(_xOrg+(i-1)*_xInc,_yOrg-15,4,0+8+128,LColor,;
trim(xlabels[i]))
end
end
next i
end
return
procedure AutoCommon(data,width,height,xOrg,yOrg,yMin,yMax)
************************************************************************
* This is stuff we need common to all the autograph routines
************************************************************************
// Fill in missing parameter values
if xOrg == nil .and. width == nil
width := 1000
end
if yOrg == nil .and. height == nil
height = 800
end
do case
case xOrg == nil
xOrg := 675 - width / 2
case width == nil
width := 1350 - 2 * xOrg
end
do case
case yOrg == nil
yOrg := 500 - height / 2
case height == nil
height := 1000 - 2 * yOrg
end
_xDivs := len(data)
// Make sure data contains an array of arrays
for i := 1 to _xDivs
data[i] := if(VALTYPE(data[i])='A',data[i],{data[i]})
next
// Determine yMin and yMax if not specified
if yMin == nil
yMin := data[1,1]
AEVAL(data,{|group| AEVAL(group, ;
{|value| if(value<>nil,yMin:=min(yMin,value), )})})
end
if yMax == nil
yMax := data[1,1]
AEVAL(data,{|group| AEVAL(group, ;
{|value| if(value<>nil,yMax:=max(yMax,value), )})})
end
_yDivs := int(height/YDENSITY+.5) // number of y axis divisions
_decimals := tic(@yMin,@yMax,@_yDivs)
_width := width
_height := height
_xOrg := xOrg
_yOrg := yOrg
_yMin := yMin
_yMax := yMax
return
************************************************************************
* Compute tic interval and adjust min & max
* Parameters:
* min0 minimum value of data set
* max0 maximum value of data set
* n requested number of axis divisions
* On return (if parameters passed by reference):
* min0 adjusted minimum value
* max0 adjusted maximum value
* n adjusted number of axis divisions
* Return value is decimal precision necessary for divisions
************************************************************************
function tic(min0,max0,n)
local a := { {1,0}, {2,0}, {2.5,1}, {5,0} }
local i:=1,e,n1,min1,max1
* compute exponent of interval
e := 10 ^ floor(log10((max0-min0)/n))
do while .T.
min1 := floor(min0/(a[i,1]*e)) * a[i,1]*e // adjust min
max1 := ceiling(max0/(a[i,1]*e)) * a[i,1]*e // adjust max
n1 := int((max1-min1) / (a[i,1]*e)) // how many divs this one?
if n1 <= n
exit
end
if ++i > len(a)
i := 1
e := e * 10
end
end
min0 := min1
max0 := max1
n := (max0-min0)/(a[i,1] * e)
return(max(a[i,2]-floor(log10(e)),0))
************************************************************************
* Returns highest integer <= x
************************************************************************
function floor(x)
return if(x<int(x),int(x)-1,int(x))
************************************************************************
* Returns lowest integer >= x
************************************************************************
function ceiling(x)
return if(x>int(x),int(x)+1,int(x))
************************************************************************
* Returns Base10 Logarithm
************************************************************************
function log10(x)
return (log(x)/log(10))